﻿
Imports System.Threading
Imports std
Imports lock_t = lockWrapper(Of locks.eventCombLock)

Public Class locked_slice_wrapper
    Inherits slice_wrapper

    Private ReadOnly l As lock_t = Nothing
    Private Const in_use As Int32 = 1
    Private Const not_in_use As Int32 = 0
    Private stopping As Int32 = not_in_use
    Private working As Int32 = not_in_use

    Public Sub New(ByVal s As islice)
        MyBase.New(s)
        l = New lock_t()
        AddHandler centrosphere.unload,
            Sub()
                atomic.eva(stopping, in_use)
                lazy_wait_when(Function() atomic.read(working) = in_use)
            End Sub
    End Sub

    Protected NotOverridable Overrides Function workon(ByVal d As _do(Of eventComb)) As eventComb
        assert(Not d Is Nothing)
        Dim ec As eventComb = Nothing
        Return New eventComb(Function() As Boolean
                                 Return waitfor(l) AndAlso
                                        goto_next()
                             End Function,
                             Function() As Boolean
                                 If Interlocked.CompareExchange(working, in_use, stopping) = not_in_use AndAlso
                                    working = in_use Then
                                     ec = d()
                                     Return assert(waitfor(ec)) AndAlso
                                            goto_next()
                                 Else
                                     Return goto_next()
                                 End If
                             End Function,
                             Function() As Boolean
                                 atomic.eva(working, not_in_use)
                                 l.release()
                                 Return (ec Is Nothing OrElse ec.end_result()) AndAlso
                                        goto_end()
                             End Function)
    End Function
End Class
